package think.in.spring.bean;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
import think.in.spring.config.ListableDemoConfig;

import java.util.Arrays;
import java.util.Map;

/**
 * 集合类型依赖查找接口--ListableBeanFactory
 + 根据Bean类型查找
 + 获取同类型Bean名称列表
 + getBeanNamesForType(Class)
 + getBeanNamesForType(ResolvableType)
 + 获取同类型Bean实例列表
 + getBeansOfType(Class)以及重载方法
 + 根据注解类型查找
 + 获取标注类型Bean名称列表
 + getBeanNamesForAnnotation(Class<? extends Annotation>)
 + 获取标注类型Bean实例列表
 + getBeansWithAnnotation(Class<? extends Annotation>)
 + 获取指定名称 + 标注类型 Bean 实例
 + findAnnotationOnBean(String,Class<? extends Annotation>)
 */
public class ListableDependencyLookupDemo {
    public static void main(String[] args) {
//        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//        context.register(ListableDemoConfig.class);
//        context.refresh();
//        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//        beanNamesForType(beanFactory);
//        beansOfType(beanFactory);
//        beanNamesForAnnotation(beanFactory);
//        beansWithAnnotation(beanFactory);
//        annotationOnBean(beanFactory);
//        context.close();
    }

    /**
     * findAnnotationOnBean方法通过BeanName获取Bean的注解，如果Bean没有匹配到返回空
     * @param beanFactory
     */
    private static void annotationOnBean(ConfigurableListableBeanFactory beanFactory) {
        Component annotationOnBean = beanFactory.findAnnotationOnBean("natatores", Component.class);
        System.out.println("findAnnotationOnBean"+annotationOnBean);
    }

    /**
     * 根据注解查询Bean对象
     * @param beanFactory
     */
    private static void beansWithAnnotation(ConfigurableListableBeanFactory beanFactory) {
        Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(Component.class);
        System.out.println("beansWithAnnotation(Component):"+beansWithAnnotation);
    }
    /**
     * 根据注解查询Bean名称
     * @param beanFactory
     */
    private static void beanNamesForAnnotation(ConfigurableListableBeanFactory beanFactory) {
        String[] beanNamesForAnnotation = beanFactory.getBeanNamesForAnnotation(Component.class);
        System.out.println("beanNamesForAnnotation(Component):"+Arrays.toString(beanNamesForAnnotation));
    }

    /**
     * 根据类型查询Bean对象
     * @param beanFactory
     */
    private static void beansOfType(ConfigurableListableBeanFactory beanFactory) {
        Map<String, ListableDemoConfig.Bird> beansOfType = beanFactory.getBeansOfType(ListableDemoConfig.Bird.class);
        System.out.println("BeansOfType:"+ beansOfType);
    }

    /**
     * 根据类型查询相关的BeanName
     * @param beanFactory
     */
    private static void beanNamesForType(ConfigurableListableBeanFactory beanFactory) {
        String[] beanNamesForType = beanFactory.getBeanNamesForType(ListableDemoConfig.Bird.class);
        System.out.println("beanNamesForType:"+ Arrays.toString(beanNamesForType));
    }
}
